﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Data;
using WebComponents.Data;

namespace WebComponents.Web.UI.WebControls
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:GroupingData runat=server></{0}:GroupingData>")]
    [ToolboxBitmap(typeof(GroupingData), "WebComponents.Web.UI.WebControls.GroupingData.GroupingData.bmp")]
    public class GroupingData : WebControl
    {
        public DataTable DataSource { get; set; }
        public string GroupFields { get; set; }
        public string CellPadding { get; set; }
        public string CellSpacing { get; set; }
        public string CssStyle { get; set; }
        public string HeaderCssClass { get; set; }
        public string HeaderCssStyle { get; set; }
        public string HeaderValign { get; set; }
        public int CurrentPageIndex { get; set; }
        public int PageSize { get; set; }
        public string DisplayRowIndex { get; set; }
        public string Border { get; set; }

        public string RowCssClass { get; set; }
        public string RowCssStyle { get; set; }
        public string RowAlign { get; set; }

        private static int TotalColumns = 0;
        private static int TotalRecords = 0;
        private static int TotalPages = 0;
        private static int SkipRows = 0;
        private static StringBuilder sb = new StringBuilder();
        private static int CurrentGrouping = 0;
        private static int TotalGroupLevels = 0;
        protected override void RenderContents(HtmlTextWriter output)
        {
            output.AddAttribute(HtmlTextWriterAttribute.Id, this.ID);
            if (GroupFields == null)
                GroupFields = "";
            try
            {
                DataTable dt = new DataTable();
                dt = DataSource;
                TotalColumns = dt.Columns.Count;
                if (DisplayRowIndex == "FirstColumn" || DisplayRowIndex == "LastColumn")
                    TotalColumns = dt.Columns.Count + 1;

                DataTable dtSource = new DataTable();
                dtSource = DataSource;

                sb.Append(String.Format(@"<table{0}{1}{2}{3}>",
                    CellPadding != null ? String.Format(" cellpadding={0}{1}{0}", "\"", CellPadding) : "",
                    CellSpacing != null ? String.Format(" cellspacing={0}{1}{0}", "\"", CellSpacing) : "",
                    Border != null ? String.Format(" border={0}{1}{0}", "\"", Border) : "",
                    HeaderCssStyle != null ? String.Format(" style={0}{1}{0}", "\"", HeaderCssStyle) : ""
                ));
                #region Grouping
                TotalGroupLevels = GroupFields.Split('|').Count();
                foreach (string groupingField in GroupFields.Split('|'))
                {
                    CurrentGrouping++;

                    var queryGroup = from t in dtSource.AsEnumerable()
                                     group t by t.Field<object>(groupingField) into grouped
                                     select grouped;

                    foreach (var group in queryGroup)
                    {

                        sb.Append(String.Format(@"<tr{0}{1}{2}>",
                            HeaderValign != null ? String.Format(" valign={0}{1}{0}", "\"", HeaderValign) : "",
                            HeaderCssClass != null ? String.Format(" class={0}{1}{0}", "\"", HeaderCssClass) : "",
                            HeaderCssStyle != null ? String.Format(" style={0}{1}{0}", "\"", HeaderCssStyle) : ""
                         ));
                        #region Blank TD Levels
                        for (int btl = 0; btl < CurrentGrouping - 1; btl++)
                        {
                            sb.Append(String.Format(@"<td>&nbsp;</td>"));
                        }
                        #endregion
                        sb.Append(String.Format(@"<td{0}{1}{2}{3}>",
                            RowAlign != null ? String.Format(" align={0}{1}{0}", "\"", RowAlign) : "",
                            RowCssClass != null ? String.Format(" class={0}{1}{0}", "\"", RowCssClass) : "",
                            RowCssStyle != null ? String.Format(" style={0}{1}{0}", "\"", RowCssStyle) : "",
                            String.Format(@" colspan={0}{1}{0}", "\"", (TotalColumns - CurrentGrouping).ToString())
                        ));
                        sb.Append(String.Format(@"{0}{1}", groupingField, CurrentGrouping == TotalGroupLevels ? " (Last Group)" : ""));
                        sb.Append(String.Format(@"</td>"));
                        sb.Append(String.Format(@"</tr>"));
                    }


                }
                #endregion
                sb.Append(String.Format(@"</table>"));


                output.Write(sb.ToString());

                /*Reset*/
                #region Reset
                sb.Clear();
                CurrentGrouping = 0;
                #endregion
          















                TotalRecords = dt.Rows.Count;
                if (String.IsNullOrEmpty(PageSize.ToString()) || PageSize <= 1)
                    PageSize = 0;
                TotalPages = Convert.ToInt32(Math.Ceiling((double)dt.Rows.Count / PageSize));

                #region Control CurrentPage
                if (CurrentPageIndex <= 1 || string.IsNullOrEmpty(CurrentPageIndex.ToString()))
                    CurrentPageIndex = 1;
                if (CurrentPageIndex >= TotalPages)
                    CurrentPageIndex = TotalPages;
                #endregion

                SkipRows = (CurrentPageIndex - 1) * PageSize;

                output.Write(String.Format("TotalRecords: {0}", TotalRecords));
                output.Write(String.Format(" TotalPages: {0} ", TotalPages));
                output.Write(String.Format(" SkipRows: {0} ", SkipRows));
                output.Write(String.Format(" CurrentPageIndex: {0} ", CurrentPageIndex));

                #region Table Attributes
                if (CellPadding != null)
                    output.AddAttribute("cellpadding", CellPadding);
                if (CellSpacing != null)
                    output.AddAttribute("cellspacing", CellSpacing);
                if (CssStyle != null)
                    output.AddAttribute("style", CssStyle);
                if (Border != null)
                    output.AddAttribute("border", Border);

                #endregion
                output.RenderBeginTag("table");
            
                #region Column Header
                output.RenderBeginTag("tr");

                if (DisplayRowIndex == "FirstColumn")
                {
                    output.RenderBeginTag("td");
                    output.Write(" ");
                    output.RenderEndTag();
                }

                if (HeaderCssClass != null)
                    output.AddAttribute("class", HeaderCssClass);
                if (HeaderCssStyle != null)
                    output.AddAttribute("style", HeaderCssStyle);
                foreach (DataColumn dc in dt.Columns)
                {
                    output.RenderBeginTag("td");
                    output.Write(dc.ColumnName);
                    output.RenderEndTag();
                }
                if (DisplayRowIndex == "LastColumn")
                {
                    output.RenderBeginTag("td");
                    output.Write(" ");
                    output.RenderEndTag();
                }
                output.RenderEndTag();
                #endregion

                #region Rows

                var query = (from t in dt.AsEnumerable()
                             select t).Skip(SkipRows).Take(PageSize);
                /* if PageSize=0 - Setting select all rows as default */
                if (PageSize == 0)
                    query = from t in dt.AsEnumerable()
                            select t;
                DataTable dtRecords = new DataTable();
                dtRecords = query.CopyToDataTable();

                int rowIndex = 0;
                foreach (DataRow dr in dtRecords.Rows)
                {
                    rowIndex++;
                    output.RenderBeginTag("tr");

                    #region DisplayRowIndex First DataRow
                    if (DisplayRowIndex == "FirstColumn")
                    {
                        output.RenderBeginTag("td");
                        output.Write((rowIndex + SkipRows).ToString());
                        output.RenderEndTag();
                    }
                    #endregion

                    foreach (DataColumn dc in dtRecords.Columns)
                    {
                        if (RowCssClass != null)
                            output.AddAttribute("class", RowCssClass);
                        output.RenderBeginTag("td");
                        output.Write(dr[dc.ColumnName].ToString());
                        output.RenderEndTag();
                    }

                    #region DisplayRowIndex Last DataRow
                    if (DisplayRowIndex == "LastColumn")
                    {
                        output.RenderBeginTag("td");
                        output.Write((rowIndex + SkipRows).ToString());
                        output.RenderEndTag();
                    }
                    #endregion

                    output.RenderEndTag();
                }
                #endregion

                output.RenderEndTag();

           }
            catch (Exception ex) { output.Write(ex.Message); }
        }

        

        protected override void Render(HtmlTextWriter writer)
        {
            this.RenderContents(writer);
        }
    }
}
